﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using PercolationTree.Drawing;
using PercolationTree.Util;
using PercolationTree.Model;
using PercolationTree.Experiments;

namespace PercolationTree
{
    public partial class Form1 : Form
    {

        private Tree currentTree;

        private int ChildrenSetting
        {
            get
            {
                try
                {
                    return int.Parse(textBox1.Text);
                }
                catch
                {
                    return 20;
                }
            }
        }

        private int LayersSetting
        {
            get
            {
                try
                {
                    return int.Parse(textBox2.Text);
                }
                catch
                {
                    return 4;
                }
            }
        }

        private float InvalidationChanceSetting
        {
            get
            {
                try
                {
                    return int.Parse(textBox3.Text) / 100.0f;
                }
                catch
                {
                    return 0.3f;
                }
            }
        }

        private int MaxNodesSetting
        {
            get
            {
                try
                {
                    return int.Parse(textBox4.Text);
                }
                catch
                {
                    return 100;
                }
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Tree tree = TreeFactory.BuildDeterminedTree(4, 6);
            tree.Percolate(0.0f);
            currentTree = tree;
            IDrawable drawable = new DrawableTree(tree);
            drawingControl1.setDrawable(drawable);
            drawingControl1.Refresh();

            IDrawable coordinates = new DrawableFunction(new Point[] { 
                new Point(0, 10),
                new Point(80, 10),
                new Point(90, 20),
                new Point(100, 200)
            });
            drawingFunctionControl.setDrawable(coordinates);
            drawingFunctionControl.Refresh();
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            SuspendLayout();
            this.tabControl1.Size = new System.Drawing.Size(this.Width - 40, this.Height - 62);
            this.drawingControl1.Size = new System.Drawing.Size(tabControl1.Width, tabControl1.Height);
            drawingControl1.Refresh();
            drawingFunctionControl.Refresh();
            ResumeLayout();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Tree tree = TreeFactory.BuildRandomTree(ChildrenSetting, LayersSetting);
            tree.Percolate(InvalidationChanceSetting);
            currentTree = tree;
            IDrawable drawable = new DrawableTree(tree);
            drawingControl1.setDrawable(drawable);
            drawingControl1.Refresh();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Tree tree = TreeFactory.BuildDeterminedTree(ChildrenSetting, LayersSetting);
            tree.Percolate(InvalidationChanceSetting);
            currentTree = tree;
            IDrawable drawable = new DrawableTree(tree);
            drawingControl1.setDrawable(drawable);
            drawingControl1.Refresh();
        }

        private void tabPage2_Enter(object sender, EventArgs e)
        {
            label7.Text = Statistics.getNodesNumber(currentTree).ToString();
            label8.Text = Statistics.getInvalidNodesNumber(currentTree).ToString();
            label9.Text = Statistics.getValidNodesNumber(currentTree).ToString();
            label11.Text = Statistics.isTreePassSignal(currentTree).ToString();
            label14.Text = Statistics.getPercentInvalidNodes(currentTree).ToString();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Tree tree = TreeFactory.BuildFixedTree(ChildrenSetting, MaxNodesSetting);
            tree.Percolate(InvalidationChanceSetting);
            currentTree = tree;
            IDrawable drawable = new DrawableTree(tree);
            drawingControl1.setDrawable(drawable);
            drawingControl1.Refresh();
        }

        private void TPCExperimentButton_Click(object sender, EventArgs e)
        {
            IExperiment experiment = new TreesPerChanceExperiment(ChildrenSetting, LayersSetting);
            ShowExperimentResults(experiment);
        }

        private void CExperimentButton_Click(object sender, EventArgs e)
        {
            IExperiment experiment = new ClastersExperiment(ChildrenSetting, LayersSetting);
            ShowExperimentResults(experiment);
        }

        private void PTExperimentButton_Click(object sender, EventArgs e)
        {
            IExperiment experiment = new PercExperiment(ChildrenSetting, LayersSetting);
            ShowExperimentResults(experiment);
        }

        private void ShowExperimentResults(IExperiment experiment)
        {
            FactoryFunction factoryFunc = checkBox1.Checked ? (FactoryFunction)TreeFactory.BuildRandomTree : (FactoryFunction)TreeFactory.BuildDeterminedTree;
            IDrawable expResults = new DrawableFunction(experiment.process(factoryFunc));
            drawingFunctionControl.setDrawable(expResults);
            drawingFunctionControl.Refresh();
        }
    }
}
